<?php
namespace app\api\common;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;
use Lcobucci\JWT\Parser;

/*
* 单例模式：一次请求中所有出现使用jwt的地方都是一个用户
* 
*/
class JwtAuth{

	private $token;
	private $iss = 'api.test.com';
	private $uid;
	private $secrect = 'sfd43@#$$fsd';

	private $decodeToken; // 用户回传回来的token

	// 饿汉式单例模式
	private static $instance;
	public static function getInstance() {
		if(is_null(self::$instance)){
			self::$instance = new self();
		}

		return self::$instance;
	}

	// 私有化构造函数，禁止在new出来对象
	private function __construct(){

	}

	private function __clone(){

	}

	public function setUid($uid){
		$this->uid = $uid;
		return $this;
	}

	public function setToken($userToken){
		$this->token = $userToken;
		return $this;
	}

	/**
	 * 向外提供一个jwt encode方法（加密）
	 */
	public function jwtEncode(){
		$time = time();
		$this->token = (new Builder())->setHeader('alg', 'HS256')
						->issuedBy($this->iss)
						->issuedAt($time)
						->expiresAt($time + 10800)
						->withClaim('uid', $this->uid)
						->getToken(new Sha256(), new Key($this->secrect)); // Retrieves the generated token
		
		return (string)$this->token;
	}


	public function parserToken(){
		if(!$this->decodeToken){
			$this->decodeToken = (new Parser())->parse((string)$this->token);
			$this->uid = $this->decodeToken->getClaim('uid');
			$this->expTime = $this->decodeToken->getClaim('exp');
		}

		return $this->decodeToken;
	}

	/**
	 * 向外暴露过期时间
	 */
	public function getExpTime(){
		if($this->decodeToken){
			return $this->expTime;
		} else {
			return null;
		}
	}

	/**
	 * 向外暴露解密后的用户id
	 */
	public function getUserId(){
		if($this->decodeToken){
			return $this->uid;
		} else {
			return null;
		}
	}

	/**
	 * 向外提供一个jwt decode方法（解密）
	 */
	public function jwtDecode(){

		$data = new ValidationData();
		$data->setIssuer($this->iss);
		$decodeRes = $this->decodeToken->verify(new Sha256(), $this->secrect);
		return $decodeRes;
	}
}